from flask import Blueprint,request,jsonify
from flask_restful import reqparse
from utils.my_redis import r
from db import db
import json
index_bp = Blueprint('index_bp',__name__,url_prefix='/index')

# 获取商家信息
@index_bp.route('/getShops')
def getShops():
    # 从redis读取
    code='001'
    key = 'shop'+code
    shop = r.get_str(key)
    if not shop:
        # 并发访问的时候，只能一个人访问
        res = r.setnx_str(key+'shop',key+'shop')
        if res:
            sql = "select * from shops where code='%s'"%(code)
            shop = db.find(sql)
            r.set_str(key,json.dumps(shop))
    else:
        shop = json.loads(shop)
    return jsonify({
        "code":200,
        "shop":shop
    })

# 获取分类接口
@index_bp.route('/getcate')
def getCate():
    # 从缓存取数据
    cates = r.get_str('cates')
    if not cates:
        sql = "select id,name from category order by sort asc"
        res = db.find_all(sql)

        data = [{'id':str(i['id']),'text':i['name']} for i in res]
        r.set_str('cates',json.dumps(data))
    else:
        data = json.loads(cates)
    return jsonify({
        "code":200,
        "cate":data
    })


# 获取分类下的商品
@index_bp.route('/getGoods')
def getGoods():
    # 获取分类id
    cateid = request.args.get('cateid')
    # r.removeall_str('goods'+cateid)
    # 从缓存取数据
    goods = r.get_str('goods'+cateid)
    # 不存在查询
    if not goods:
        sql = "select id,name,price,image,description from dish where category_id=%d and is_deleted=0"%int(cateid)
        res = db.find_all(sql)
        # 把decimal转成float
        data = []
        # 根据菜品id查询对应的口味信息
        for i in res:
            dict = {
                'id':str(i['id']),
                'name':i['name'],
                'price': float(i['price']),
                'image': i['image'],
                'description': i['description'],
                'flavors':[]
            }
            sql1 = "select value from dish_flavor where dish_id=%d"%int(i['id'])
            flavors = db.find_all(sql1)
            flist=[]
            for j in flavors:
                flist.append(json.loads(j['value']))
            dict['flavors'] = flist
            data.append(dict)
        # 加入缓存
        r.set_str('goods'+cateid,json.dumps(data))
    else:
        data = json.loads(goods)
    return jsonify({
        "code":200,
        "goods":data
    })


# 购物车添加
@index_bp.route('/addcate')
def addcart():
    # 获取参数
    userid = request.args.get('userid')
    gid = request.args.get('gid')
    count = request.args.get('count')
    type = request.args.get('type')
    flavors = request.args.get('flavors')
    # if not all [userid,gid,count,type,flavors]:
    #     return jsonify({'code':400,'msg':'参数错误'})
    # 查询购物车中某个商品是否存在
    pkey = 'cart' + str(userid) + 'goods' + str(gid)
    flag = r.is_exits(pkey)
    if int(flag)==0:
        # 不存在添加
        r.hash_add(pkey,gid,count)
        r.hash_add(pkey,'type',type)
        r.hash_add(pkey,'flavors',json.dumps(flavors))

    else:
        r.hash_hincrby(pkey,gid,count,1)
    # 返回结果
    return jsonify({
        "code":200,
        "msg":'购买成功'
    })

# 我的购物车数据封装
def getcartdata(userid):
    # 根据userid模糊查询购物车信息
    carts = r.findall_str('cart' + str(userid))
    # 遍历购物车，查每一个商品的属性
    clist = []
    tmoney = 0
    tcount = 0
    for i in carts:
        dict = {}
        goods = r.hash_getall(i.decode())
        for k, v in goods.items():
            kk = k.decode()
            vv = v.decode()
            if kk == "type":
                dict['type'] = vv
            elif kk == 'flavors':
                dict['flavors'] = json.loads(vv)
            else:
                dict['id'] = kk
                dict['count'] = vv
                tcount += int(vv)

        clist.append(dict)
    if len(clist) > 0:
        # 根据商品id查询数据库价格
        for i in clist:
            # 根据id和类型查询名称和价格  1单品 2套餐
            if i['type'] == 1:
                sql = "select name,price,image from dish where id=%d" % int(i['id'])
            else:
                sql = "select name,price,image from dish where id=%d" % int(i['id'])
            res = db.find(sql)
            # 重组
            i['name'] = res['name']
            i['price'] = float(res['price'])
            i['image'] = float(res['price'])
            tmoney += int(i['count']) * i['price']
    return clist,tmoney,tcount



# 我的购物车
@index_bp.route('/myshop')
def myshop():
    # 获取userid
    userid = request.args.get('userid')
    # 返回结果 [{'id':'1',}]
    clist,tmoney,tcount = getcartdata(userid)
    return jsonify({'code':200,'clist':clist,'tmoney':tmoney,'tcount':tcount})


@index_bp.route('/text1')
def text():
    list1 = [
        {
            'id':1,
            'name':'手机',
            'pid':0
        },
        {
            'id':2,
            'name':'电器',
            'pid':0
        },
        {
            'id':3,
            'name':'vivo手机',
            'pid':1
        },
        {
            'id':4,
            'name':'iQZ6',
            'pid':3
        },{
            'id':5,
            'name':'电视',
            'pid':2
        },{
            'id':6,
            'name':'海尔电视',
            'pid':5
        }
    ]

    al_list = []
    dict = {}
    for j in list1:
        # {{'id':1},{}}
        dict[j['id']] = j
        # print('1',dict)
    for i in list1:
        # print('4',dict)
        pid = i['pid']
        if pid == 0:
            al_list.append(i)
            print('11',al_list)

        else:
            if 'son' not in dict[pid]:
                dict[pid]['son'] = []
            # 因为共同指向同一块地址，跟浅拷贝是一个原理
            dict[pid]['son'].append(i)
            # 怎么就变成这样了
            print('333',al_list)
            print('444',i)

    return jsonify({
        'code':200,
        'list':al_list
    })

def ctree(data):
    # 判断data长度
    list1 = []
    if len(data)<0:
        return list1
    # 重组
    dict = {}
    # 先把数据重组成字典形式
    for i in data:
        dict[i['code']] = i
    for j in data:
        pid = j['pid']
        if pid == None:
            list1.append(j)
        else:
            # 判断父类下是否有son
            if 'son' not in dict[pid]:
                dict[pid]['son'] = []
            # 因为指向同一个地址，共享数据所以list1中数据会发生变化
            dict[pid]['son'].append(j)
    return list1

# 无限极分类、省市区
@index_bp.route('/clist')
def clist():
    # redis
    list = r.get_str('ctree')
    if not list:
        sql = "select * from tb_areas"
        res = db.find_all(sql)
        list1 = ctree(res)
        r.set_str('ctree',json.dumps(list1))
    else:
        list1 = json.loads(list)
    return jsonify({
        "code":200,
        "list":list1
    })

@index_bp.route('/jiajian')
def jiajian():
    # 获取参数
    userid = request.args.get('userid')
    gid = request.args.get('gid')
    count = request.args.get('count')
    type = request.args.get('type')
    # 判断redis是否存在购物车
    if r.is_exits('cart' + str(userid) + 'goods' + str(gid)):
        # 存在对count进行增加和减少
        # 1 是减
        if int(type)==2 and int(count)>0:
            # 减
            hcount = '-'+ count
        else:
            # 2 是加
            hcount = count
        res = r.hash_hincrby('cart' + str(userid) + 'goods' + str(gid), gid, hcount,type)
        if res == False:
            return jsonify({
                "code":400,
                "msg":'减的数量必须小于当前买的'
            })
        else:
            return jsonify({
                "code":200,
                "msg":'ok'
            })
    else:
        return jsonify({
            "code":400,
            "msg":'此商品购物车不存在'
        })


# @index_bp.route('/address')
# def address():


@index_bp.route('/address',methods=['POST','GET'])
def address():
    if request.method == 'GET':
        userid = request.args.get('userid')
        key = 'address' + userid
        data = r.get_str(key)
        if not data:
            sql = 'select * from address_book where user_id=%s' % userid
            list = db.find_all(sql)
            data = []
            xid = 1
            for i in list:
                print(i['is_default'])
                if i['is_default'] == 1:
                    i['is_default'] = True
                else:
                    i['is_default'] = False
                dict = {
                    'id': i['id'],
                    'name': i['consignee'],
                    'tel': i['phone'],
                    'address': i['detail'],
                    'isDefault': i['is_default']
                }
                data.append(dict)
            r.set_str(key, json.dumps(data))
        else:
            data = json.loads(data)
        return jsonify({'code': 200, "list": data})
    elif request.method == 'POST':
        # 获取用户输入
        req = reqparse.RequestParser()
        req.add_argument('userid',required=True)
        req.add_argument('sex',type=1,default=1)
        req.add_argument('province',required=True)
        req.add_argument('city',required=True)
        req.add_argument('county',required=True)
        req.add_argument('addressDetail',required=True)
        req.add_argument('tel',required=True)
        req.add_argument('name',required=True)
        req.add_argument('isDefault', type=bool)
        args = req.parse_args()
        print(type(args['isDefault']))
        if args['isDefault'] is True:
            sql = 'update address_book set is_default=%s where user_id=%s'%(0,args['userid'])
            args['isDefault'] = 1
            db.update(sql)
            db.commit()
        else:
            args['isDefault'] = 0
        try:
            import datetime
            create_time = datetime.datetime.strftime(datetime.datetime.now(),'%Y%m%d%H%M%S')
            print(type(args['province']))
            sql = f"insert into address_book(sex,province_name,city_name,district_name,detail,phone,consignee,create_time,update_time,create_user,update_user,user_id,is_default) values('{args['sex']}','{args['province']}','{args['city']}','{args['county']}','{args['addressDetail']}','{args['tel']}','{args['name']}','{create_time}','{create_time}',{1},{1},'{args['userid']}','{args['isDefault']}')"
            print(sql)
            db.update(sql)
            db.commit()
            key = 'address'+args['userid']
            r.removeall_str(key)
            return jsonify({"code":200,"msg":"添加成功"})
        except:
            return jsonify({"code":20011,"msg":"添加失败"})


# @index_bp.route('/address',methods=['PUT'])
# def address():
#     # 获取用户输入
#     req = reqparse.RequestParser()
#     req.add_argument('userid', required=True)
#     req.add_argument('sex', type=1, default=1)
#     req.add_argument('province', required=True)
#     req.add_argument('city', required=True)
#     req.add_argument('county', required=True)
#     req.add_argument('addressDetail', required=True)
#     req.add_argument('tel', required=True)
#     req.add_argument('name', required=True)
#     req.add_argument('isDefault', type=bool)
#     args = req.parse_args()
import datetime
import random
@index_bp.route('/add_orders',methods=['POST'])
def add_orders():
    # 获取用户输入
    # "userid":300,
    #         'address_id':this.chosenAddressId,'message':this.message,'paytype':this.paytype
    data = json.loads(request.data)
    userid = data['userid']
    address_id = data['address_id']
    message = data['message']
    paytype = data['paytype']
    # 根据购物车查价格图片
    # redis hash获取我的购物车
    clist, tmoney, tcount = getcartdata(userid)
    # 事务处理s
    # 写入订单表
    # 订单号  年月日时分秒+userid+5位随机数
    if len(clist)>0:
        now = datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d%H%M%S')
        code = datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d%H%M%S') + str(userid) + str(
            random.randint(10000, 99999))
        # code = random.randint(10000,99999)
        try:
            sql1 = "select consignee,phone,province_name,city_name,district_name,detail from address_book where id=%d" % int(address_id)
            res = db.find(sql1)
            address = res['province_name'] + res['city_name'] + res['district_name'] + res['detail']
                # 写入订单表
            sql = "insert into orders(number,status,user_id,address_book_id,order_time,checkout_time,pay_method,amount,remark,phone,address,user_name,consignee)" \
                  "values('%s',%d,%d,%d,'%s','%s',%d,'%s','%s','%s','%s','%s','%s')" % (
                  code, 1, int(userid), int(address_id), now, '2022-8-31 10:00:00', int(paytype), str(tmoney), message,
                  res['phone'], address, res['consignee'], res['consignee'])
            print(sql)
            db.update(sql)
            # 写入详情表
            for i in clist:
                if int(i['type']) == 1:
                    dish_id = i['id']
                    setmeal_id = 0
                else:
                    dish_id = 0
                    setmeal_id = i['id']

                sql1 = "insert into order_detail(name,image,order_id,dish_id,setmeal_id,dish_flavor,number,amount) values ('%s','%s','%s',%d,%d,'%s',%d,'%s')" % (
                    i['name'], i['image'], int(code), int(dish_id), int(setmeal_id), json.dumps(i['flavors']),
                    int(i['count']),
                    float(i['price']))
                print(sql1)
                db.update(sql1)
            db.commit()
            # 清空购物车
            r.removeall_str('cart' + str(userid))
            return jsonify({
                "code": 200,
                'order_code': code
            })
        except Exception as e:
            print(e)
            db.rollback()
            return jsonify({
                "code": 20010
            })
    else:
        return jsonify({'code':20011,'msg':'没有可以生成订单的数据'})

from flask import redirect
from procom import get_ali_object
@index_bp.route('/getpayurl')
def getpayurl():
    order_code = request.args.get('order_code')
    sql = "select amount from orders where number='%s'"%(order_code)
    res = db.find(sql)
    if res:
        r.set_add('payorderlist',order_code)
        alipay = get_ali_object()
        return_url = "http://localhost:8000/callback"
        query_params = alipay.direct_pay("a订单支付", str(order_code), float(res['amount']), return_url)
        # query_params = alipay.direct_pay(subject="a订单支付", out_trade_no='1111', total_amount='123',return_url=return_url)
        pay_url = 'https://openapi.alipaydev.com/gateway.do?{0}'.format(query_params)
        return jsonify({'code': 200, "url": pay_url})
    # return redirect(pay_url)
    else:
        return jsonify({'code': 200, "msg":'没有可以生成订单的数据' })


@index_bp.route('/callback')
def callback():
    trade_no = request.args.get('trade_no') # 流水号
    out_trade_no = request.args.get('out_trade_no')# 订单号
    try:
        # 从ser清除
        r.set_delvalue('payorderlist',out_trade_no)
        # 更新订单表
        now = datetime.datetime.strftime(datetime.datetime.now(),'%Y-%m-%d %H:%M:%S')
        sql = "update orders set status=2,trade_no='%s',checkout_time='%s' where number='%s'"%(str(trade_no),now,str(out_trade_no))
        db.update(sql)
        sql1 = "select dish_id,setmeal_id,number from order_detail where order_id='%s'"%out_trade_no
        res = db.find_all(sql1)
        for i in res:
            if int(i['dish_id'])>0:
                dsql = "update dish set sales=sales+%d where id=%d"%(int(i['number']),int(i['dish_id']))
            else:
                dsql = "update dush_flavor set sales=sales+%d where id=%d"%(int(i['number']),int(i['setmeal_id']))
                c_sql = "select dish_id from dish_flavor where id=%d"%int(i['setmeal_id'])
                re=db.find(c_sql)
                dsql1 = "update dish set sales=sales+1 where id=%d"%int(re['dish_id'])
                db.update(dsql1)
            db.update(dsql)
        db.commit()
        return jsonify({'code':200,"msg":"支付成功"})
    except Exception as e:
        print(e)
        db.rollback()
        return jsonify({'code':400,"msg":"支付失败"})



